1. Field of the Invention
The present invention relates in general to storage systems, and particularly to, systems and methods for dynamically scanning a plurality of active ports for work.
2. Description of the Related Art
In, for example, a Fibre Channel storage device, there is a host adapter card that handles all Fibre Channel protocol interactions. It is a common practice for each adapter card to have one or more ports and some adapter cards have up to eight ports. It is also becoming a common practice to include two or more processors handling work on the adapter card.
With the added complexity of having multiple processors handling multiple ports, additional requirements are involved to maintain the integrity of port-centric data structures when performing work on a port (e.g., two processors cannot read/write to the same port-based data structures). A common practice to overcome this situation is to have a port lock allowing only one processor to process work for one port at a time. While this configuration solves the problem, this configuration also prevents the other processor from doing work for this port, which may potentially contaminate the port-centric data structures.
In addition, this configuration carries a large performance hit in two ways. First, port locks are “expensive” with respect to time, especially when a port lock is not required. Furthermore, because both processors are trying to process all of the work for the ports, there will be a lot of conflicts between the processors. Second, the processors typically spend a relatively large amount of time handling or checking if port work is available on a port that may not have any work.
One known solution is to minimize port locks by “peeking” for work first. Peeking can be done by looking at key data structures and determining if there is any work for the port. If there is work, a port lock is obtained and the work is completed. If there is no work to be done, this work is skipped. The downside to peeking is that the processors are still trying to process work for all of the ports and conflicts between processors can still occur. Also, there could be a dozen different categories of work a port has to do and peeking at each category before grabbing a port lock can be expensive and complicated to implement.
Another known solution is to create port affinity by assigning half the ports to one processor while the other half of the ports are assigned to the other processor. While this removes the possibility of the processors having port lock conflicts, it is not an acceptable solution due to the fact that port usage is dynamic. For example, if a first processor is assigned port_0 and port_1 and a second processor is assigned port_2 and port_3, this configuration works if all four ports are in use and when each processor is processing the same number of ports (e.g., the first processor is processing port_0 and the second processor is processing port_2, the first processor is processing port_0 and the second processor is processing port_3, the first processor is processing port_1 and the second processor is processing port_2, and the first processor is processing port_1 and the second processor is processing port_3). However, this configuration is inefficient when port_0 and port_1 are both being used while port_2 and port_3 are idle, or when port_2 and port_3 are both being used while port_0 and port_1 are idle because the benefit of having two processors is lost since only processor is processing work in each situation, which is unacceptable.